home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Communication / Chat / Source / ChatController.m < prev    next >
Text File  |  1992-10-13  |  5KB  |  166 lines

  1. /* ChatController by Andrew Loewenstern (andrew@cubetech.com).*/
  2.  /*  This is a really simple */
  3.  /* class that clearly shows you how to implement Distributed Objects */
  4.  /* in a NeXTSTEP application.  This example is totally free, and */
  5.  /* there is no warranty.  If you have questions about it, send me */
  6.  /* some mail at andrew@cubetech.com. */
  7.  
  8. #import "ChatController.h"
  9. #import <remote/NXProxy.h>
  10.  
  11. @implementation ChatController
  12.  
  13. - getHostName            /* gets the host of the server app */
  14. {
  15.   [NXApp runModalFor:[hostName window]];
  16.   [[hostName window] close];
  17.   return self;
  18. }
  19.  
  20. - appDidInit:sender
  21. {
  22.   NXConnection *conn;
  23.   
  24.   [self getHostName];        /* get the host of the server */
  25.   
  26.                 /* try to connect to server */
  27.   server = [NXConnection connectToName:"ChatServer" onHost:[hostName
  28.                                 stringValue]];
  29.   if(!server)            /* we must be the server */
  30.     {
  31.                 /* allocate the client list */
  32.       clients = [[List allocFromZone:[self zone]] init];
  33.                 /* register ourselves */
  34.       conn = [NXConnection registerRoot:self withName:"ChatServer"];
  35.       [[conversation window] setTitle:"ChatServer"];
  36.       server = self;        /* messages we send to the server will */
  37.                 /* now go to us... */
  38.       weAreServer = YES;
  39.     }
  40.   else                /* we must be the client */
  41.     {
  42.                 /* Get the connection for the server */
  43.       conn = [server connectionForProxy];
  44.                 /* tell the runtime system that the */
  45.                 /* server responds to the Chat */
  46.                 /* protocol */
  47.       [server setProtocolForProxy:@protocol(Chat)];
  48.       
  49.       weAreServer = NO;
  50.       [server checkIn:self];    /* check in with the server */
  51.     }
  52.                 /* we want to know if either the */
  53.                 /* server or the clients die... */
  54.   [conn registerForInvalidationNotification:self];
  55.   [conn runFromAppKit];        /* handle messages in the main event */
  56.                 /* loop */
  57.   [entry selectText:self];
  58.   return self;
  59. }
  60.  
  61. - checkIn:
  62.   sender
  63. {
  64.   if(weAreServer)
  65.     {
  66.                 /* stuff the client into the list so */
  67.                 /* we can send messages to it...*/
  68.       [clients addObjectIfAbsent:sender];
  69.                 /* and tell the runtime system that */
  70.                 /* the client implements the Chat */
  71.                 /* protocol */
  72.       [sender setProtocolForProxy:@protocol(Chat)];
  73.     }
  74.   return self;
  75. }
  76.  
  77. - checkOut:
  78.   sender
  79. {
  80.   if(weAreServer)
  81.     [clients removeObject:sender]; /* remove the client so we don't */
  82.                    /* send messages to it anymore */
  83.   return self;
  84. }
  85.  
  86.  
  87.                 /* acceptMessage:from: is sent by the */
  88.                 /* server to every client.  It returns */
  89.                 /* void so the server does not wait */
  90.                 /* for each client to accept the */
  91.                 /* message and return...*/
  92.  
  93. - (void) acceptMessage:(in char *)message from:(in char *)name
  94. {
  95.   int i;
  96.   char *comp = NXZoneMalloc([self zone], strlen(name) +
  97.                 strlen(message) + 4);
  98.  
  99.                 /* create the string to put in the */
  100.                 /* conversation window */
  101.   sprintf(comp, "%s: %s\n", name, message);
  102.   
  103.                 /* then select the very last line, */
  104.                 /* replace the selection with the */
  105.                 /* string, select the last line again, */
  106.                 /* and scroll it till it's visible */
  107.   [conversation setSel:[conversation textLength] :[conversation
  108.                            textLength]];
  109.   [conversation replaceSel:(const char *)comp];
  110.   [conversation setSel:[conversation textLength] :[conversation
  111.                            textLength]];
  112.   [conversation scrollSelToVisible];
  113.   
  114.   NXZoneFree([self zone], comp); /* free the string */
  115.  
  116.  
  117.                 /* for each client, we send the same */
  118.                 /* acceptMesage:from: message.  Each */
  119.                 /* client will recieve it and display */
  120.                 /* the mesage */
  121.   if(weAreServer)
  122.     {
  123.       for(i = 0; i < [clients count]; i++)
  124.     [[clients objectAt:i] acceptMessage:message from:name];
  125.     }
  126. }
  127.  
  128.       
  129. - senderIsInvalid:
  130.   sender            /* we will recieve this message if the */
  131.                 /* server dies, or if a client dies */
  132.                 /* (if we are the server */
  133. {
  134.   if(weAreServer)        /* then remove the client */
  135.     [self checkOut:sender];
  136.   else                /* if there's no server, then we die */
  137.     [NXApp terminate:self];
  138.   
  139.   return self;
  140. }
  141.  
  142. - send:sender
  143. {
  144.                 /* send the message to the server! */
  145.                 /* It's as simple as this! */
  146.   [server acceptMessage:[entry stringValue] from:getlogin()];
  147.   [entry selectText:self];
  148.   return self;
  149. }
  150.  
  151. - appWillTerminate:
  152.   sender
  153. {
  154.                 /* if we are a client, we should tell */
  155.                 /* the server not to send us messages. */
  156.                 /* Although the server will get a */
  157.                 /* senderIsInvalid message, it's */
  158.                 /* better to make sure the server */
  159.                 /* doesn't try to contact us after we */
  160.                 /* no longer exist... */
  161.   if(!weAreServer)
  162.     [server checkOut:self];
  163.   return self;
  164. }
  165. @end
  166.